package mk.jug.academy.service;

import java.util.Date;

import mk.jug.academy.dao.ContentDAO;
import mk.jug.academy.model.Content;
import mk.jug.academy.model.ContentStatus;
import mk.jug.academy.model.Page;
import mk.jug.academy.model.User;
import mk.jug.academy.model.UserType;
import mk.jug.academy.preconditions.ContentPreconditions;
import mk.jug.academy.preconditions.PreconditionExceptions;
import mk.jug.academy.util.Utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;


/**
 * Contains the business logic implementation for the {@link ContentService}.
 *
 * @author Ice.Penov
 */
@Service
public class ContentServiceImpl implements ContentService {

	@Autowired private ContentDAO contentDAO;
	
	@Override @Transactional
	public void save(Content content, User user) {
		ContentPreconditions.save(content, user);
		content.setStatus(ContentStatus.SAVED);
		content.setCreatorID(user.getId());
		content.setCreatorType(UserType.valueOf(user.getRole()));
		content.setCreatorDisplayName(user.getDisplayName());
		contentDAO.save(content);
	}
	
	@Override @Transactional
	public void publish(Content content) {
		ContentPreconditions.publish(content);
		content.setPublishDate(new Date());
		content.setStatus(ContentStatus.PUBLISHED);
		contentDAO.save(content);
	}

	@Override
	public Page<Content> listSaved(int pageNumber, int itemsPerPage) {
		return contentDAO.findByStatus(ContentStatus.SAVED, Utils.calculateStart(pageNumber, itemsPerPage), itemsPerPage);
	}
	
	@Override
	public Page<Content> listPublished(int pageNumber, int itemsPerPage) {
		return contentDAO.findByStatus(ContentStatus.PUBLISHED, Utils.calculateStart(pageNumber, itemsPerPage), itemsPerPage);
	}

	@Override
	public Page<Content> listDeleted(int pageNumber, int itemsPerPage) {
		return contentDAO.findByStatus(ContentStatus.DELETED, Utils.calculateStart(pageNumber, itemsPerPage), itemsPerPage);
	}
	
	@Override @Transactional
	public void delete(Content content) {
		ContentPreconditions.delete(content);
		content.setStatus(ContentStatus.DELETED);		
		contentDAO.save(content);
	}
	
	@Override
	public Content load(Long id) {
		return contentDAO.find(Content.class, id);
	}
	
	@Override
	public void saveChanges(Content content) {
		Assert.notNull(content.getId(), PreconditionExceptions.ID_IS_NULL);
		contentDAO.save(content);
	}

	@Override
	public Page<Content> listSavedAsCreator(int pageNumber, int itemsPerPage,
			Long creatorID) {
		return contentDAO.findByStatusAndCreator(ContentStatus.SAVED, Utils.calculateStart(pageNumber, itemsPerPage), itemsPerPage, creatorID);
	}
	
	@Override
	public Page<Content> listPublishedAsCreator(int pageNumber,
			int itemsPerPage, Long creatorID) {
		return contentDAO.findByStatusAndCreator(ContentStatus.PUBLISHED, Utils.calculateStart(pageNumber, itemsPerPage), itemsPerPage, creatorID);
	}

	@Override
	public Page<Content> listDeletedAsCreator(int pageNumber, int itemsPerPage,
			Long creatorID) {
		return contentDAO.findByStatusAndCreator(ContentStatus.DELETED, Utils.calculateStart(pageNumber, itemsPerPage), itemsPerPage, creatorID);
	}

}